﻿using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Primitives;
using System.ComponentModel.DataAnnotations.Schema;

namespace XYS.Service.Core
{
    /// <summary>
    /// 映射全局配置
    /// </summary>
    public static class GlobalSettingExtension
    {
        /// <summary>
        /// 添加映射全局配置
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="globalSettingType"></param>
        /// <returns></returns>
        public static WebApplicationBuilder AddGlobalSetting(this WebApplicationBuilder builder, Type globalSettingType)
        {
            //映射全局参数
            SetGlobalSetting(builder.Configuration, globalSettingType);
            return builder;
        }

        /// <summary>
        /// 增加侦听配置变化事件
        /// </summary>
        /// <param name="app"></param>
        /// <param name="globalSettingType"></param>
        /// <returns></returns>
        public static WebApplication UseGlobalSettingChange(this WebApplication app, Type globalSettingType)
        {
            //增加侦听配置变化事件
            _ = ChangeToken.OnChange(app.Configuration.GetReloadToken, () => SetGlobalSetting(app.Configuration, globalSettingType));
            return app;
        }

        /// <summary>
        /// 映射全局参数
        /// </summary>
        /// <param name="configuration"></param>
        /// <param name="globalSettingType"></param>
        public static void SetGlobalSetting(IConfiguration configuration, Type globalSettingType)
        {
            var ignoreAttributeFullNames = new List<string>()
            {
                 typeof(NotMappedAttribute).FullName??"",
                  typeof(System.Text.Json.Serialization.JsonIgnoreAttribute).FullName??"",
                  typeof(Newtonsoft.Json.JsonIgnoreAttribute).FullName??"",
            };

            var properties = globalSettingType.GetProperties().Where(x => x.CanWrite && !x.CustomAttributes.Any(a => ignoreAttributeFullNames.Contains(a.AttributeType.FullName ?? ""))).ToList();
            foreach (var property in properties)
            {
                var value = configuration.GetSection(property.Name).Get(property.PropertyType);
                if (value != null) property.SetValue(null, value);
            }
        }

    }
}
